package com.carol.lmsbe.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.carol.lmsbe.dto.*;
import com.carol.lmsbe.entity.Equipment;
import com.carol.lmsbe.entity.Laboratory;
import com.carol.lmsbe.entity.User;
import com.carol.lmsbe.mapper.EquipmentMapper;
import com.carol.lmsbe.mapper.LaboratoryMapper;
import com.carol.lmsbe.mapper.UserMapper;
import com.carol.lmsbe.service.EquipmentService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 设备管理服务实现
 */
@Service
@RequiredArgsConstructor
@Slf4j
public class EquipmentServiceImpl implements EquipmentService {

    private final EquipmentMapper equipmentMapper;
    private final LaboratoryMapper laboratoryMapper;
    private final UserMapper userMapper;

    @Override
    public Page<EquipmentDTO> listEquipment(EquipmentQueryRequest request) {
        Page<Equipment> page = new Page<>(request.getPageNum(), request.getPageSize());
        
        LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>();
        
        if (StringUtils.hasText(request.getCategory())) {
            queryWrapper.eq(Equipment::getCategory, request.getCategory());
        }
        // 智能搜索：如果同时有name和code参数且值相同，则使用OR查询指定字段
        if (StringUtils.hasText(request.getName()) && StringUtils.hasText(request.getCode()) 
            && request.getName().equals(request.getCode())) {
            // 使用OR查询：设备编号、设备名称、规格、厂家匹配
            queryWrapper.and(wrapper -> wrapper
                .like(Equipment::getCode, request.getName())
                .or()
                .like(Equipment::getName, request.getName())
                .or()
                .like(Equipment::getSpecification, request.getName())
                .or()
                .like(Equipment::getManufacturer, request.getName())
            );
        } else {
            // 单独查询
            if (StringUtils.hasText(request.getName())) {
                queryWrapper.like(Equipment::getName, request.getName());
            }
            if (StringUtils.hasText(request.getCode())) {
                queryWrapper.like(Equipment::getCode, request.getCode());
            }
        }
        if (StringUtils.hasText(request.getStatus())) {
            queryWrapper.eq(Equipment::getStatus, request.getStatus());
        }
        if (request.getLaboratoryId() != null) {
            queryWrapper.eq(Equipment::getLaboratoryId, request.getLaboratoryId());
        }
        if (request.getPurchaseDateStart() != null) {
            queryWrapper.ge(Equipment::getPurchaseDate, request.getPurchaseDateStart());
        }
        if (request.getPurchaseDateEnd() != null) {
            queryWrapper.le(Equipment::getPurchaseDate, request.getPurchaseDateEnd());
        }
        if (StringUtils.hasText(request.getManufacturer())) {
            queryWrapper.like(Equipment::getManufacturer, request.getManufacturer());
        }
        
        queryWrapper.orderByDesc(Equipment::getCreateTime);
        
        Page<Equipment> equipmentPage = equipmentMapper.selectPage(page, queryWrapper);
        
        // 转换为DTO
        Page<EquipmentDTO> result = new Page<>();
        BeanUtils.copyProperties(equipmentPage, result, "records");
        
        List<EquipmentDTO> records = equipmentPage.getRecords().stream().map(equipment -> {
            EquipmentDTO dto = new EquipmentDTO();
            BeanUtils.copyProperties(equipment, dto);
            
            // 设置实验室名称
            if (equipment.getLaboratoryId() != null) {
                Laboratory laboratory = laboratoryMapper.selectById(equipment.getLaboratoryId());
                if (laboratory != null) {
                    dto.setLaboratoryName(laboratory.getName());
                }
            }
            
            return dto;
        }).collect(Collectors.toList());
        
        result.setRecords(records);
        return result;
    }

    @Override
    public EquipmentDTO getEquipmentById(Long id) {
        Equipment equipment = equipmentMapper.selectById(id);
        if (equipment == null) {
            throw new RuntimeException("设备不存在");
        }
        
        EquipmentDTO dto = new EquipmentDTO();
        BeanUtils.copyProperties(equipment, dto);
        
        // 设置实验室名称
        if (equipment.getLaboratoryId() != null) {
            Laboratory laboratory = laboratoryMapper.selectById(equipment.getLaboratoryId());
            if (laboratory != null) {
                dto.setLaboratoryName(laboratory.getName());
            }
        }
        
        return dto;
    }

    @Override
    @Transactional
    public EquipmentDTO createEquipment(EquipmentCreateRequest request) {
        // 检查设备编号是否已存在
        LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Equipment::getCode, request.getCode());
        Equipment existingEquipment = equipmentMapper.selectOne(queryWrapper);
        if (existingEquipment != null) {
            throw new RuntimeException("设备编号已存在");
        }
        
        Equipment equipment = new Equipment();
        BeanUtils.copyProperties(request, equipment);
        
        equipmentMapper.insert(equipment);
        
        return getEquipmentById(equipment.getId());
    }

    @Override
    @Transactional
    public EquipmentDTO updateEquipment(EquipmentUpdateRequest request) {
        Equipment equipment = equipmentMapper.selectById(request.getId());
        if (equipment == null) {
            throw new RuntimeException("设备不存在");
        }
        
        // 检查设备编号是否已被其他设备使用
        if (!equipment.getCode().equals(request.getCode())) {
            LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(Equipment::getCode, request.getCode());
            queryWrapper.ne(Equipment::getId, request.getId());
            Equipment existingEquipment = equipmentMapper.selectOne(queryWrapper);
            if (existingEquipment != null) {
                throw new RuntimeException("设备编号已被其他设备使用");
            }
        }
        
        BeanUtils.copyProperties(request, equipment);
        equipmentMapper.updateById(equipment);
        
        return getEquipmentById(equipment.getId());
    }

    @Override
    @Transactional
    public void deleteEquipment(Long id) {
        Equipment equipment = equipmentMapper.selectById(id);
        if (equipment == null) {
            throw new RuntimeException("设备不存在");
        }
        
        equipmentMapper.deleteById(id);
    }

    @Override
    public EquipmentStatisticsResponse getEquipmentStatistics(EquipmentStatisticsRequest request) {
        EquipmentStatisticsResponse response = new EquipmentStatisticsResponse();
        
        // 这里可以实现具体的统计逻辑
        // 由于涉及复杂的统计查询，暂时返回空数据
        // 实际实现中可以使用自定义SQL查询
        
        return response;
    }

    @Override
    public List<String> getAllCategories() {
        LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Equipment::getCategory);
        queryWrapper.groupBy(Equipment::getCategory);
        
        List<Equipment> equipmentList = equipmentMapper.selectList(queryWrapper);
        return equipmentList.stream()
                .map(Equipment::getCategory)
                .filter(StringUtils::hasText)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    public List<String> getAllStatuses() {
        LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(Equipment::getStatus);
        queryWrapper.groupBy(Equipment::getStatus);
        
        List<Equipment> equipmentList = equipmentMapper.selectList(queryWrapper);
        return equipmentList.stream()
                .map(Equipment::getStatus)
                .filter(StringUtils::hasText)
                .distinct()
                .collect(Collectors.toList());
    }

    @Override
    @Transactional
    public void batchDeleteEquipment(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return;
        }
        
        equipmentMapper.deleteBatchIds(ids);
    }

    @Override
    public byte[] exportEquipmentData(EquipmentQueryRequest request) {
        // 这里可以实现Excel导出逻辑
        // 暂时返回空数组
        return new byte[0];
    }

    @Override
    public List<EquipmentDTO> getAvailableEquipments() {
        // 查询状态为"NORMAL"的设备（可用状态）
        LambdaQueryWrapper<Equipment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Equipment::getStatus, "NORMAL");
        queryWrapper.orderByAsc(Equipment::getName);
        
        List<Equipment> equipmentList = equipmentMapper.selectList(queryWrapper);
        return equipmentList.stream().map(equipment -> {
            EquipmentDTO dto = new EquipmentDTO();
            BeanUtils.copyProperties(equipment, dto);
            return dto;
        }).collect(Collectors.toList());
    }
}
